import React, {useState} from "react";
import {OpFile} from "@/services/api-functions";
import {getBase64, isSuccess} from "@/utils/utils";
import {ProFormUploadButton, ProFormUploadDragger} from "@ant-design/pro-form";
import {RcFile} from "antd/lib/upload/interface";
// @ts-ignore
import {OssDto} from "@/services/api-types";
import {message, Modal} from "antd";
import COS from "cos-js-sdk-v5";

interface UploadFormProps {
  type: 'formal' | 'private' | 'public'
  name: string
  rules?: any[]
  accept?: string
  label?: string
  max?: number
  required?: boolean
  multiple?: boolean
  drag?: boolean
  preview?: 'none' | 'view' | 'open'
  fileList?: OssDto[]
  hideUploadList?: boolean
  success: (file: OssDto) => void
  remove: (arr: OssDto[]) => void
}

export const getUploadConfig = (tp: 'formal' | 'private' | 'public', fileName: string) => {
  return tp === 'formal'
    ? OpFile.formalUpload(fileName)
    : OpFile.publicUpload(fileName)
}

// @ts-ignore
const UploadForm: React.FC<UploadFormProps> = ({
                                                 required,
                                                 drag,
                                                 type,
                                                 name,
                                                 rules,
                                                 accept,
                                                 label,
                                                 max,
                                                 multiple,
                                                 preview,
                                                 success,
                                                 fileList,
                                                 remove,
                                                 hideUploadList
                                               }) => {

  const [upConfig, setUpConfig] = useState<any | undefined>(undefined);

  const [visible, setVisible] = useState<boolean>(false)
  const [current, setCurrent] = useState<{ name: string, preview: string } | undefined>(undefined)

  const props = {
    required: !!required,
    rules: rules ?? [],
    showUploadList: !hideUploadList,
    name,
    label,
    max,
    accept,
    // action: upConfig?.url,
    fieldProps: {
      name: 'file',
      customRequest: (option: any) => {
        if(upConfig){
          const file = option.file as File
          try {
            let cos = new COS({
              getAuthorization:(options: any, callback: Function)=>{
                callback({
                  TmpSecretId: upConfig.tmpSecretId,
                  TmpSecretKey: upConfig.tmpSecretKey,
                  SecurityToken: upConfig.sessionToken,
                  StartTime: upConfig.startTime,
                  ExpiredTime: upConfig.expiredTime
                })
              }
            })
            // 使用第三方服务进行文件上传
            cos.putObject({
              Bucket: upConfig?.bucket, /* 必须 */
              Region: upConfig?.region,    /* 必须 */
              Key:  upConfig?.key,              /* 必须 */
              StorageClass: 'STANDARD',
              Body: file, // 上传文件对象
              onProgress: function(progressData) {
                console.log(JSON.stringify(progressData));
              }
            }, function(err, data) {
              console.log(err || data);
            });
            // onSuccess的回调参数可以在 UploadFile.response 中获取
            option.onSuccess(upConfig?.url)
            success({name: file.name, key: upConfig?.fileKey})
          } catch (error) {
            option.onError(error)
          }
        }else{
          message.error('上传出错，请重试')
          option.onError('上传出错，请重试')
        }
      },
      multiple: !!multiple,
      onPreview: async (file: any) => {
        if (preview === 'none' || (preview === 'open' && !file.url)) {
          message.error('暂不支持预览')
          return
        }
        if (preview === 'open') {
          window.open(file.url)
          return
        }
        setCurrent({
          name: file.name || file.url.substring(file.url.lastIndexOf('/') + 1),
          preview: file.url || await getBase64(file.originFileObj)
        })
        setVisible(true)
      },
      beforeUpload: (file: RcFile) => new Promise((resolve, reject) => getUploadConfig(type, file.name)
        .then(({code, data}) => {
          if (isSuccess(code)) {
            setUpConfig(data ?? undefined)
            resolve(file)
          } else {
            message.error('上传出错，请刷新重试')
            reject()
          }
        })),
      onRemove: (file: any) => {
        if (remove) {
          remove(fileList?.filter(item => file.id ? file.id !== item.id : file.name !== item.name) ?? [])
        }

      }
    }
  }
  return [
    <Modal
      visible={visible && current != undefined}
      title={current?.name}
      footer={null}
      onCancel={() => setVisible(false)}
    >
      <img alt={current?.name} style={{width: '100%'}} src={current?.preview}/>
    </Modal>,
    drag ? <ProFormUploadDragger {...props} /> : <ProFormUploadButton {...props} />
  ]
};

export default UploadForm;
